package com.example.amazing_wangjj.aitools;

import com.example.amazing_wangjj.pojo.SealSampleInfo;
import com.example.amazing_wangjj.service.SealSampleService;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 封样桶编码工具类
 * 提供给AI的工具，用于生成商品混凝土原材料封样桶的编码
 */
@Component("sealSampleTools")
public class SealSampleTools {

    @Autowired
    private SealSampleService sealSampleService;

    // 材料类型映射表
    private static final Map<String, String> MATERIAL_CODE_MAP = new HashMap<>();
    static {
        MATERIAL_CODE_MAP.put("石子", "01");
        MATERIAL_CODE_MAP.put("机制砂", "02");
        MATERIAL_CODE_MAP.put("天然砂", "03");
        MATERIAL_CODE_MAP.put("水泥", "04");
        MATERIAL_CODE_MAP.put("粉煤灰", "05");
        MATERIAL_CODE_MAP.put("外加剂", "06");
        MATERIAL_CODE_MAP.put("矿粉", "07");
    }

    /**
     * 生成封样桶编码工具
     * 根据申请信息生成瓶盖码和瓶身码，并输出Excel文件
     */
    @Tool(name = "生成封样桶编码", value = "根据企业编码、申请数量、材料类型和适用月份，生成商品混凝土原材料封样桶的编码，并输出Excel文件。")
    public String generateSealSampleCodes(
            @P(value = "企业编码，可选值：8888、6666") String companyCode,
            @P(value = "申请数量，每批最多50个") int applyCount,
            @P(value = "材料类型，可选值：石子、机制砂、天然砂、水泥、粉煤灰、外加剂、矿粉") String materialType,
            @P(value = "适用月份，格式：YYYYMM") String applicableMonth
    ) {
        try {
            // 验证企业编码
            if (!"8888".equals(companyCode) && !"6666".equals(companyCode)) {
                return "生成失败：无效的企业编码，只能是8888或6666";
            }

            // 验证申请数量
            if (applyCount > 50 || applyCount <= 0) {
                return "生成失败：申请数量必须在1-50之间";
            }

            // 验证材料类型
            if (!MATERIAL_CODE_MAP.containsKey(materialType)) {
                return "生成失败：无效的材料类型";
            }

            // 验证适用月份格式
            if (!applicableMonth.matches("\\d{6}")) {
                return "生成失败：适用月份格式错误，应为YYYYMM";
            }

            // 获取当前日期作为申请时间
            String applyTime = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            String dateStr = applyTime.replace("-", "");

            // 检查是否今天已经申请过
            if (sealSampleService.hasAppliedToday(companyCode, applyTime)) {
                return "生成失败：该企业今天已经申请过封样桶编码";
            }

            // 生成编码
            List<SealSampleInfo> sealSampleInfos = new ArrayList<>();
            for (int i = 1; i <= applyCount; i++) {
                SealSampleInfo info = new SealSampleInfo();
                info.setBottleCapCode(generateBottleCapCode(companyCode, dateStr, i));
                info.setBottleBodyCode(generateBottleBodyCode(companyCode, materialType, applicableMonth, i));
                info.setMaterialType(materialType);
                info.setApplicableMonth(applicableMonth);
                info.setApplyTime(applyTime);
                info.setCompanyCode(companyCode);
                sealSampleInfos.add(info);
            }

            // 保存记录并导出Excel
            String filePath = sealSampleService.saveAndExportExcel(sealSampleInfos);

            return "生成成功，Excel文件路径：" + filePath;
        } catch (Exception e) {
            return "生成失败：" + e.getMessage();
        }
    }

    /**
     * 生成瓶盖码(≤16位)
     * 规则：企业编码(4位) + 日期(8位，格式：YYYYMMDD) + 批次序号(4位)
     */
    private String generateBottleCapCode(String companyCode, String dateStr, int sequence) {
        return companyCode + dateStr + String.format("%04d", sequence);
    }

    /**
     * 生成瓶身码(≤22位)
     * 规则：企业编码(4位) + 材料类型编码(2位) + 适用月份(6位，格式：YYYYMM) + 序号(4位) + 校验位(6位)
     */
    private String generateBottleBodyCode(String companyCode, String materialType, String month, int sequence) {
        String materialCode = MATERIAL_CODE_MAP.getOrDefault(materialType, "00");
        String baseCode = companyCode + materialCode + month + String.format("%04d", sequence);
        String checkDigit = generateCheckDigit(baseCode);
        return baseCode + checkDigit;
    }

    /**
     * 生成校验位
     */
    private String generateCheckDigit(String baseCode) {
        int sum = 0;
        for (char c : baseCode.toCharArray()) {
            sum += c;
        }
        return String.format("%06d", sum % 1000000);
    }
}